package com.networklib.task.base;


import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.networklib.TaskResult;
import com.networklib.task.TaskResultCode;
import com.networklib.task.WeakHandler;

import java.util.UUID;
import java.util.concurrent.Callable;

public abstract class ATask implements Callable<TaskResult>, Cloneable {
    private String tag = UUID.randomUUID().toString();
    private boolean isDone;
    private TaskListener taskListener;
    private Handler innerHandler;

    public final TaskResult call() {
        TaskResult taskResult = new TaskResult(this.tag, TaskResultCode.SUCCESS);
        try {
            if (!this.before(taskResult)) {
                this.setIsDone(true);
                this.doFinish(taskResult);
                taskResult.setResultCode(TaskResultCode.NONE);
                return taskResult;
            }

            taskResult = this.doExecute(taskResult);
        } catch (Exception e) {
            e.printStackTrace();
            TaskResultCode taskResultCode = TaskResultCode.FAILURE;
            taskResultCode.setOtherMsg(e.getMessage());
            taskResult.setResultCode(taskResultCode);
            taskResult.setResult(null);
        } finally {
            try {
                this.setIsDone(true);
                this.doFinish(taskResult);
                this.after(taskResult);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return taskResult;
    }

    protected abstract TaskResult doExecute(TaskResult taskResult);

    protected boolean before(TaskResult taskResult) {
        return taskListener == null || taskListener.before(taskResult);
    }

    private void doFinish(TaskResult taskResult) {
        if (taskListener != null) {
            taskListener.onComplete(taskResult);
        }
    }

    protected void finish(TaskResult taskResult) {
        if (taskListener != null) {
            taskListener.onComplete(taskResult);
        }
    }

    protected void after(TaskResult taskResult) {
        if (taskListener != null) {
            taskListener.after(taskResult);
        }
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public void setIsDone(boolean isDone) {
        this.isDone = isDone;
    }

    public boolean isDone() {
        return isDone;
    }

    public void setDone(boolean isDone) {
        this.isDone = isDone;
    }


    public void setTaskListener(TaskListener taskListener) {
        this.taskListener = taskListener;
    }


    public interface TaskListener {

        void onComplete(TaskResult taskResult);

        void after(TaskResult taskResult);

        boolean before(TaskResult taskResult);
    }
}
